package com.chen.base.utils.security;

import java.security.SecureRandom;

/**
 * 随机密码生成工具类
 * @author ChenJinLong
 */
public class PasswordGeneratorUtil {

    /** 小写字母 **/
	private static final String LOWERCASE_CHARACTERS = "abcdefghijklmnopqrstuvwxyz";
    /** 大写字母 **/
    private static final String UPPERCASE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    /** 数值 **/
    private static final String DIGITS = "0123456789";
    /** 特殊字符 **/
    private static final String SPECIAL_CHARACTERS = "!@#$%^&*_=+-/";
    /** 剩余字符选取范围 **/
    private static final String ALL_CHARACTERS = LOWERCASE_CHARACTERS + UPPERCASE_CHARACTERS + DIGITS;
 
	/**
	 * 生成含有指定小写字母、大写字母和数字字符以及特殊字符数量和固定长度的随机密码
     * @param length 密码长度
	 */
	private static String generatePassword(int length) {
        // 小写字母数量
		int lowerCaseCount = 1;
        // 大写字母数量
		int upperCaseCount = 1;
        // 数字数量
		int numberCount = 1;
        // 特殊字符数量
		int specialCount = 1;

        StringBuilder randomStr = new StringBuilder(length);
        SecureRandom random = new SecureRandom();

        // 随机生成大写字母部分
        for (int i = 0; i < lowerCaseCount; i++) {
            int lowerCaseIndex = random.nextInt(LOWERCASE_CHARACTERS.length());
            randomStr.append(LOWERCASE_CHARACTERS.charAt(lowerCaseIndex));
        }
        // 随机生成小写字母部分
        for (int i = 0; i < upperCaseCount; i++) {
            int upperCaseIndex = random.nextInt(UPPERCASE_CHARACTERS.length());
            randomStr.append(UPPERCASE_CHARACTERS.charAt(upperCaseIndex));
        }
        // 随机生成数字部分
        for (int i = 0; i < numberCount; i++) {
            int digitsIndex = random.nextInt(DIGITS.length());
            randomStr.append(DIGITS.charAt(digitsIndex));
        }
        // 随机生成特殊字符部分
        for (int i = 0; i < specialCount; i++) {
            int specialIndex = random.nextInt(SPECIAL_CHARACTERS.length());
            randomStr.append(SPECIAL_CHARACTERS.charAt(specialIndex));
        }
        // 生成剩余的字符
        for (int i = lowerCaseCount + upperCaseCount + numberCount + specialCount; i < length; i++) {
        	// 在所有字符里面取剩下的字符
            randomStr.append(ALL_CHARACTERS.charAt(random.nextInt(ALL_CHARACTERS.length())));
        }
        // 洗牌字符，使其顺序随机
        return shuffleString(randomStr.toString());
	}
	
	/**
	 * 用于洗牌字符串中的字符
	 */
    private static String shuffleString(String input) {
    	 SecureRandom random = new SecureRandom();
        char[] characters = input.toCharArray();
        for (int i = characters.length - 1; i > 0; i--) {
            int randomIndex = random.nextInt(i + 1);
            char temp = characters[i];
            characters[i] = characters[randomIndex];
            characters[randomIndex] = temp;
        }
        return new String(characters);
    }

    public static void main(String[] args) {
        // 一次性生成的密码数量
        int passwordCount = 10;
        for (int i = 0; i < passwordCount; i++) {
            System.out.println(generatePassword(50));
        }
    }
}